package com.onepice.mlp.api.config;

import com.alibaba.fastjson.JSONObject;
import com.onepice.mlp.utils.commom.PropertiesUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 过滤器，用于过滤请求的url，判断用户登录状态
 *
 * @author FireWang
 * @date 2021/11/08
 */
@Component
@Slf4j
public class RouteFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
            throws IOException, ServletException {
        try {
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            HttpServletResponse response = (HttpServletResponse) servletResponse;

            log.info("当前请求url：" + request.getRequestURI());

            /**
             * 过滤器白名单，白名单内的请求可直接访问
             */
            if (dofiltration(request)) {
                filterChain.doFilter(request, response);
                return;
            }

            /**
             * 其他请求，先校验取出用户缓存做登录状态校验,校验不通过则直接跳转登录页
             */
            HttpSession session = request.getSession();
            UserProfile userProfile = (UserProfile) session.getAttribute("userProfile");

            //用户尚未登录，直接返回登录页
            if (userProfile == null || userProfile.getCurrentUserId() < 0) {
                log.info("当前的用户会话认证无效，需重新登录........contextpath[" + request.getContextPath() + "]");
                //判断是否是ajax请求,是的话设置请求超时，直接返回登录页
                String requested = "x-requested-with";
                if (request.getHeader(requested) != null &&
                        "XMLHttpRequest".equals(request.getHeader(requested))) {
                    log.info("ajax请求：" + request.getRequestURI());
                    setTimeOut(response);
                } else {
                    //方法2可实现跳转，从新生成一个servlet，url会变化
                    response.sendRedirect(request.getContextPath() + "/login");
                }
                return;
            } else {
                //已经有过登录记录的用户，判断是否失效
                if (userProfile.getCurrentUserstatus() != 1) {
                    log.info("当前的用户会话认证无效，需重新登录........contextpath[" + request.getContextPath() + "]");
                    response.sendRedirect(request.getContextPath() + "/login");
                    return;
                }

                //对于已经登录的用户，若访问登录页面路径，则返回歌曲列表
                if (request.getRequestURI().equals(request.getContextPath()) ||
                        request.getRequestURI().equals(request.getContextPath() + "/")) {
                    response.sendRedirect(request.getContextPath() + "/weather/list");
                    return;
                }

                //设置用户IP
                userProfile.setCurrentUserLoginIp(request.getRemoteAddr());
            }

            //验证登录通过，对访问连接进行向下传递处理
            filterChain.doFilter(request, response);

        } catch (Exception e) {
            log.info("过滤器异常：" + e.getMessage());
        }
    }

    /**
     * ajax请求超时处理
     *
     * @param response
     */
    private void setTimeOut(HttpServletResponse response) {
        try {
            JSONObject json = new JSONObject();
            json.put("obj1", "登录超时，请重新登录！");
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/json;charset=utf-8");
            PrintWriter out = null;
            out = response.getWriter();
            out.write(json.toString());
        } catch (Exception e) {
            log.info("过滤器异常：" + e.getMessage());
            e.printStackTrace();
            response.setHeader("sessionStatus", "timeout");
        }
    }

    /**
     * 接口访问跳过过滤规则
     *
     * @param request
     */
    private boolean dofiltration(HttpServletRequest request) {
        /**
         * 示例页面路径：/{rootPath}/login/index.html
         * request.getRequestURI()返回：/{rootPath}/login/index.html
         * request.getContextPath()返回：/{rootPath}
         * request.getServletPath()返回：/login/index.html
         */
        try {
            //获取项目根路径
            String rootPath = PropertiesUtil.getDataFromPropertiseFile("versionInfo", "rootPath");

            //跳过静态资源访问
            String staticpath = request.getContextPath() + "/static";

            //管理后台登录页面跳过过滤规则
            String login = rootPath + "/login", dologin = rootPath + "/dologin", dologout = rootPath + "/dologout";

            //平台公共接口跳过过滤规则
            String webservice = rootPath + "/webservice";

            //测试接口跳过过滤规则
            String testApi = rootPath + "/weather/test";

            if (request.getRequestURI().startsWith(staticpath) ||
                    request.getRequestURI().equals(login) ||
                    request.getRequestURI().equals(dologin) ||
                    request.getRequestURI().equals(dologout) ||
                    request.getRequestURI().contains(webservice) ||
                    request.getRequestURI().contains(testApi)) {
                return true;
            }
        } catch (Exception e) {
            log.info("过滤器异常：" + e.getMessage());
            e.printStackTrace();
            return false;
        }
        return false;
    }

}

